--元表
--任何表变量都可以作为另一个表变量的元表
--任何表变量都可以有自己的元表
--相当于父类
--当在子表中执行特定操作时会执行元表中的内容

--设置元表
meta={}
myTable={}
--设置元表函数
setmetatable(myTable,meta) --子表，元表（父）

--特定操作

--__tostring
meta2={
	--当子表被当作字符串使用时会默认调用元表的__tostring方法
	--会默认传入子表作为变量
	__tostring=function(t)
		return t.name
	end
}
myTable2={
	name="我"
}

setmetatable(myTable2,meta2)
print(myTable2)

--__call
meta3={
	--当子表被当作函数使用时会默认调用__call
	--第一个参数默认是子表
	__call=function(a,b)
		print(a)
		print(b)
		print("你")
	end
}
myTable3={}
setmetatable(myTable3,meta3)
myTable3(1)

--运算符重载
meta4={
	--运算符重载
	__add=function(t1,t2)
		return t1.age+t2.age
	end,

	__sub=function(t1,t2)
		return t1.age-t2.age
	end

	--乘：__mul
	--除: __div
	--取余: __mod
	--幂: __pow

	--如果要用条件运算符来比较两个表
	--那么这两个表的元表一定要一致
	--没有>和>=

	--==: __eq
	--< :__lt
	--<=:__le
	--..(拼接):__concat
}
myTable4={
	age=1
}
setmetatable(myTable4,meta4)
myTable5={
	age=2
}
print(myTable4+myTable5)
print(myTable4-myTable5)

--_index和__newindex
meta6Father={
	age=3
}
meta6Father.__index=meta6Father
meta6={
	--age=1
}
setmetatable(meta6,meta6Father)
meta6.__index=meta6
--meta6.__index={age=2}
myTable6={}
setmetatable(myTable6,meta6)

--_index 当子表中找不到某一个属性
--会到元表中__index中指定的表去找索引
--__index的赋值最好写在外部
--__index可以一层层往上套用

print(myTable6.age)
--rawget就是在自己身上找有没有这个索引
print(rawget(myTable6,"age"))

--__newindex 当赋值时，如果找不到索引
--那么会把这个值赋到newindex所指的表中，不会修改自己
meta7={}
meta7.__newindex={}
myTable7={}
setmetatable(myTable7,meta7)
myTable7.age=1
print(myTable7.age)
print(meta7.__newindex.age)

--一样在自己身上设置，忽略__newindex
rawset(myTable7,"age",2)
print(myTable7.age)

--获取元表
print(getmetatable(myTable6))